package client.comm.commlib.comm_ui

import android.Manifest
import android.annotation.TargetApi
import android.content.Context
import android.content.Intent
import android.graphics.BitmapFactory
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.widget.ImageView
import android.widget.Toast
import androidx.core.widget.ContentLoadingProgressBar
import androidx.lifecycle.viewModelScope
import androidx.viewpager.widget.PagerAdapter
import androidx.viewpager.widget.ViewPager.OnPageChangeListener
import client.comm.commlib.R
import client.comm.commlib.base.BaseActivity
import client.comm.commlib.comm_ui.ImageGalleryActivity
import client.comm.commlib.comm_ui.vm.ImageGalleryViewModel
import client.comm.commlib.databinding.ActivityImageGalleryBinding
import client.comm.commlib.toast.toast
import client.comm.commlib.utils.Util
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import pub.devrel.easypermissions.AfterPermissionGranted
import pub.devrel.easypermissions.AppSettingsDialog
import pub.devrel.easypermissions.EasyPermissions
import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks
import java.io.File
import java.util.concurrent.Future

class ImageGalleryActivity : BaseActivity<ImageGalleryViewModel, ActivityImageGalleryBinding>(),
    OnPageChangeListener, PermissionCallbacks {
    private var mImageSources: Array<String>? = null
    private var mImageSources2: ArrayList<Uri>? = null
    var len = 0
    private var mCurPosition = 0
    private var mNeedSaveLocal = false
    private var isLocal = false
    private var mNeedCookie = false
    private lateinit var mImageDownloadStatus: BooleanArray
    override fun initBundle(bundle: Bundle?) {
        intent?.let {
            isLocal = it.getBooleanExtra("isLocal", false)
            if (isLocal) {
                mImageSources2 = it.getParcelableArrayListExtra<Uri>(KEY_IMAGE) as ArrayList<Uri>?

                mImageSources2?.apply {
                    len = size
                }
            } else {
                mImageSources = it.getStringArrayExtra(KEY_IMAGE)

                mImageSources?.apply {
                    len = size
                    mImageDownloadStatus = BooleanArray(size)
                }
            }

            mCurPosition = it.getIntExtra(KEY_POSITION, 0)
            mNeedSaveLocal = it.getBooleanExtra(KEY_NEED_SAVE, true)
            mNeedCookie = it.getBooleanExtra(KEY_COOKIE, false)
        }


    }

    override fun initViewModel(): ImageGalleryViewModel = createViewModel()
    override fun setTheme() {
        window.setLayout(
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.MATCH_PARENT
        )
    }

    override fun getLayout(): Int {
        return R.layout.activity_image_gallery
    }

    override fun initView() {
        title = ""
        binding.vpImage.addOnPageChangeListener(this)
    }

    override fun initData() {


        if (mCurPosition < 0 || mCurPosition >= len) mCurPosition = 0

        // If only one, we not need the text to show
        if (len == 1) binding.tvIndex.visibility = View.GONE
        binding.vpImage.setAdapter(ViewPagerAdapter())
        binding.vpImage.setCurrentItem(mCurPosition)
        // First we call to init the TextView
        onPageSelected(mCurPosition)
    }

    private fun changeSaveButtonStatus(isShow: Boolean) {
        if (mNeedSaveLocal) {
            binding.ivSave.setVisibility(if (isShow) View.VISIBLE else View.GONE)
        } else binding.ivSave.setVisibility(View.GONE)
    }

    private fun updateDownloadStatus(pos: Int, isOk: Boolean) {
        mImageDownloadStatus[pos] = isOk
        if (mCurPosition == pos) {
            changeSaveButtonStatus(isOk)
        }
    }

    @AfterPermissionGranted(PERMISSION_ID)
    fun saveToFileByPermission(view: View?) {
        val permissions = arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE)
        if (EasyPermissions.hasPermissions(this, *permissions)) {
            saveToFile()
        } else {
            EasyPermissions.requestPermissions(this, "请授予保存图片权限", PERMISSION_ID, *permissions)
        }
    }

    override fun onPermissionsGranted(requestCode: Int, perms: List<String>) {}
    override fun onPermissionsDenied(requestCode: Int, perms: List<String>) {
        toast("没有外部存储权限！")
        if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
            AppSettingsDialog.Builder(this).build().show()
        }
    }

    private fun saveToFile() {
        if (Environment.getExternalStorageState() != Environment.MEDIA_MOUNTED) {
            Toast.makeText(this, "没有外部存储", Toast.LENGTH_SHORT).show()
            return
        }


        viewModel.viewModelScope.launch {

            binding.isShowLoading = true
            val returnUri: Uri? = withContext(Dispatchers.IO) {
                var uri: Uri? = null
                val path = mImageSources!![mCurPosition]

                // In this save max image size is source
                val future: Future<File> = mImgLoader.downloadOnly().load(path).submit(
                    Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL
                )
                var sourceFile: File? = null
                try {
                    sourceFile = future.get()
                    if (sourceFile == null || !sourceFile.exists()) {

                    } else {
                        val extension: String = Util.getExtension(sourceFile.absolutePath)
                        uri = Util.copyFile(
                            sourceFile,
                            String.format("IMG_%s.%s", System.currentTimeMillis(), extension),
                            contentResolver
                        )

                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                }

                uri
            }

            withContext(Dispatchers.Main) {
                binding.isShowLoading = false

                if (returnUri != null) {
                    sendBroadcast(
                        Intent(
                            Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
                            returnUri
                        )
                    )
                    toast("保存成功")
                } else {
                    toast("保存失败")
                }

            }
        }

    }

    override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
    override fun onPageSelected(position: Int) {
        mCurPosition = position
        binding.tvIndex.text = String.format("%s/%s", position + 1, len)
        // 滑动时自动切换当前的下载状态
        if (!isLocal)
            changeSaveButtonStatus(mImageDownloadStatus[position])
    }

    override fun onPageScrollStateChanged(state: Int) {}


    private inner class ViewPagerAdapter : PagerAdapter() {
        private var mFinishClickListener: View.OnClickListener? = null
        override fun getCount(): Int {
            return len
        }

        override fun isViewFromObject(view: View, `object`: Any): Boolean {
            return view === `object`
        }

        override fun instantiateItem(container: ViewGroup, position: Int): Any {
            val view: View = LayoutInflater.from(container.context)
                .inflate(R.layout.lay_gallery_page_item_contener, container, false)
            val previewView = view.findViewById<ImageView>(R.id.iv_preview)
            val loading = view.findViewById<View>(R.id.loading) as ContentLoadingProgressBar
            val defaultView = view.findViewById<View>(R.id.iv_default) as ImageView
            if (isLocal) {
                loading.hide()
                mImgLoader.load(mImageSources2!![position]).into(previewView)
            } else {
                mImgLoader.load(mImageSources!![position])
                    .listener(object : RequestListener<Drawable?> {
                        override fun onLoadFailed(
                            e: GlideException?,
                            model: Any,
                            target: Target<Drawable?>,
                            isFirstResource: Boolean
                        ): Boolean {
                            e?.printStackTrace()
                            loading.hide()

                            defaultView.visibility = View.VISIBLE
                            if (!isLocal)
                                updateDownloadStatus(position, false)
                            return false
                        }

                        override fun onResourceReady(
                            resource: Drawable?,
                            model: Any,
                            target: Target<Drawable?>,
                            dataSource: DataSource,
                            isFirstResource: Boolean
                        ): Boolean {
                            loading.hide()
                            if (!isLocal)
                                updateDownloadStatus(position, true)
                            return false
                        }
                    }).override(Target.SIZE_ORIGINAL).into(previewView)
            }
            // Do load
            previewView.setOnClickListener(listener)
            container.addView(view)
            return view
        }

        private val listener: View.OnClickListener
            private get() {
                if (mFinishClickListener == null) {
                    mFinishClickListener = View.OnClickListener { finish() }
                }
                return mFinishClickListener!!
            }

        override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
            container.removeView(`object` as View)
        }


    }


    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    fun resetOptions(options: BitmapFactory.Options) {
        options.inTempStorage = null
        options.inDither = false
        options.inScaled = false
        options.inSampleSize = 1
        options.inPreferredConfig = null
        options.inJustDecodeBounds = false
        options.inDensity = 0
        options.inTargetDensity = 0
        options.outWidth = 0
        options.outHeight = 0
        options.outMimeType = null
        if (Build.VERSION_CODES.HONEYCOMB <= Build.VERSION.SDK_INT) {
            options.inBitmap = null
            options.inMutable = true
        }
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)

        // Forward results to EasyPermissions
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this)
    }

    internal interface DoOverrideSizeCallback {
        fun onDone(overrideW: Int, overrideH: Int, isTrue: Boolean)
    }


    companion object {
        const val KEY_IMAGE = "images"
        const val KEY_COOKIE = "cookie_need"
        const val KEY_POSITION = "position"
        const val KEY_NEED_SAVE = "save"

        @JvmOverloads
        fun show(context: Context, images: String?, needSaveLocal: Boolean = true) {
            if (images == null) return
            show(context, arrayOf(images), 0, needSaveLocal)
        }

        fun show(context: Context, images: String?, needSaveLocal: Boolean, needCookie: Boolean) {
            if (images == null) return
            show(context, arrayOf(images), 0, needSaveLocal, needCookie)
        }

        @JvmOverloads
        fun show(
            context: Context,
            images: Array<String>?,
            position: Int,
            needSaveLocal: Boolean = true,
            needCookie: Boolean = false
        ) {
            if (images == null || images.size == 0) return
            //        if (images.length == 1 && !images[0].endsWith(".gif") && !images[0].endsWith(".GIF") && !needCookie) {
//            LargeImageActivity.show(context, images[0]);
//            return;
//        }
            val intent = Intent(context, ImageGalleryActivity::class.java)
            intent.putExtra(KEY_IMAGE, images)
            intent.putExtra(KEY_POSITION, position)
            intent.putExtra(KEY_NEED_SAVE, needSaveLocal)
            intent.putExtra(KEY_COOKIE, needCookie)
            context.startActivity(intent)
        }

        private const val PERMISSION_ID = 0x0001
    }
}